package com.joysuch.wwyt.workflow.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.joysuch.wwyt.core.bean.SimpleSelectListBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiCoreException;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.workflow.bean.*;
import com.joysuch.wwyt.workflow.entity.WorkFlowProcess;
import com.joysuch.wwyt.workflow.entity.WorkFlowProcessCodeStrategy;
import com.joysuch.wwyt.workflow.entity.WorkflowProcessPrintTemplate;
import com.joysuch.wwyt.workflow.entity.bo.ComponentStatisticBO;
import com.joysuch.wwyt.workflow.service.WorkFlowProcessScheduleService;
import com.joysuch.wwyt.workflow.service.WorkFlowProcessService;
import com.joysuch.wwyt.workflow.service.WorkflowProcessPrintTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.ActivitiException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/workflow")
@Api(tags = "业务流程配置管理")
@CrossOrigin
public class WorkFlowProcessController {

    @Autowired
    private WorkFlowProcessService workFlowProcessService;
    @Autowired
    private WorkFlowProcessScheduleService scheduleService;
    @Autowired
    private WorkflowProcessPrintTemplateService workflowProcessPrintTemplateService;

    @Autowired
    private BaseConfigService baseConfigService;


    @GetMapping("/page")
    @ApiOperation(value = "01 业务流程列表(分页）", response = WorkFlowProcess.class)
    public ResultBean page(Pageable pageable) {
        try {
            pageable = PageDataUtils.addOrderByDesc(pageable, "id");
            Page<WorkFlowProcess> pageList = workFlowProcessService.findByPage(pageable);
            return ResultBean.pageData(pageList);
        } catch (Exception e) {
            log.error("获取业务流程列表失败", e);
            throw new ActivitiException("获取业务流程列表失败", e);
        }

    }

    @RequiresPermissions("workflow:add")
    @PostMapping("/add")
    @ApiOperation(value = "新增业务流程", response = WorkFlowProcessBean.class)
    public ResultBean add(@RequestBody WorkFlowProcessBean bean) {
        workFlowProcessService.add(bean);
        return ResultBean.defaultSuccessResult();
    }

    @RequiresPermissions("workflow:update")
    @PostMapping("/update")
    @ApiOperation(value = "修改业务流程", response = WorkFlowProcessBean.class)
    public ResultBean update(@RequestBody WorkFlowProcessBean bean) {
        workFlowProcessService.update(bean);
        return ResultBean.defaultSuccessResult();
    }

    @RequiresPermissions("workflow:model:update")
    @PostMapping("/updateProcessModel")
    @ApiOperation(value = "保存业务流程模板")
    public ResultBean updateProcessModel(@RequestBody ProcessModelConfigBean bean) {
        try {
            workFlowProcessService.saveProcessModelConfig(bean);
        } catch (JsonProcessingException e) {
            log.error("保存业务流程模板失败", e);
            throw new ActivitiException("保存业务流程模板失败", e);
        }
        return ResultBean.defaultSuccessResult();
    }

    @RequiresPermissions("workflow:form:update")
    @PostMapping("/updateProcessForm")
    @ApiOperation(value = "保存业务流程表单")
    public ResultBean updateProcessForm(@RequestBody ProcessFormConfigBean bean) {
        workFlowProcessService.saveProcessFormConfig(bean);
        return ResultBean.defaultSuccessResult();
    }


    @GetMapping("/getById/{id}")
    @ApiOperation(value = "获取详情", response = WorkFlowProcessBean.class)
    @ApiImplicitParam(name = "id", value = "业务流程ID", paramType = "path", required = true)
    public ResultBean getById(@PathVariable Long id) {

        return ResultBean.success(workFlowProcessService.findDetailById(id));

    }

    @RequiresPermissions("workflow:delete")
    @GetMapping("/delete/{id}")
    @ApiOperation(value = "业务流程删除")
    @ApiImplicitParam(name = "id", value = "业务流程ID", paramType = "path", required = true)
    public ResultBean delete(@PathVariable Long id) {
        try {
            workFlowProcessService.deleteById(id);
            return ResultBean.success("");
        } catch (Exception e) {
            log.error("业务流程删除失败", e);
            throw new ActivitiException("删除业务流程失败", e);
        }
    }

    @RequiresPermissions("workflow:menu:delete")
    @GetMapping("/deleteMenu/{id}")
    @ApiOperation(value = "菜单删除")
    @ApiImplicitParam(name = "id", value = "菜单ID", paramType = "path", required = true)
    public ResultBean deleteMenu(@PathVariable Long id) {
        try {
            workFlowProcessService.deleteMenuByMenuId(id);
            return ResultBean.success("");
        } catch (Exception e) {
            log.error("业务流程菜单删除失败", e);
            throw new ActivitiException("业务流程菜单删除失败", e);
        }
    }

    @RequiresPermissions("workflow:deploy")
    @GetMapping("/deploy/{processId}")
    @ApiOperation(value = "部署业务流程")
    @ApiImplicitParam(name = "processId", value = "业务流程ID", paramType = "path", required = true)
    public ResultBean deploy(@PathVariable Long processId) {
        try {
            workFlowProcessService.deployWorkFlowProcess(processId);
            return ResultBean.success("业务流程部署成功");
        } catch (ApiCoreException er) {
            log.error(er.getMessage(), er);
            return ResultBean.fail(er.getCode(), er.getMessage());
        } catch (IOException e) {
            log.error("业务流程部署失败", e);
            return ResultBean.fail(Status.PROCESS_DEPLOY_ERROR);
        }
    }


    @GetMapping("/getProcessByName")
    @ApiOperation(value = "获取表单及流程信息", response = WorkFlowProcess.class)
    public ResultBean getProcessByName(String processName) {
        WorkFlowProcess workFlowProcess = workFlowProcessService.findByBizName(processName);
        if (workFlowProcess == null) {
            log.error("业务流程不存在或流程尚未部署： " + processName);
            throw new ActivitiException("业务流程不存在或流程尚未部署");
        }
        return ResultBean.success(workFlowProcess);

    }

    @GetMapping("/getFields")
    @ApiOperation(value = "获取表单及流程字段", response = ComponentStatisticBO.class)
    public ResultBean getFields(String processName){
        BaseConfig config = baseConfigService.findFirstConfig(BaseConfigCodes.NEW_WORKFLOW_SWITCH);
        if (config!=null&&"1".equals(config.getValue())) {
            //引擎流2.0
            List<ComponentStatisticBO> list = workFlowProcessService.getV2Fields(processName);
            return ResultBean.success(list);
        }
        List<ComponentStatisticBO> list = workFlowProcessService.getFields(processName);
        return ResultBean.success(list);
    }

    @GetMapping("/simpleList")
    @ApiOperation(value = "已部署业务流程列表")
    public ResultBean simpleList() {
        try {
            List<WorkFlowProcessSimpleBean> list = workFlowProcessService.findSimpleList();
            return ResultBean.success(list);
        } catch (Exception e) {
            log.error("获取业务流程列表失败", e);
            throw new ActivitiException("获取业务流程列表失败", e);
        }

    }

    @GetMapping("/dataSource/{type}")
    @ApiImplicitParam(name = "type", value = "数据源类型，目前只有'人员'和'承包商人员'", paramType = "path", required = true)
    @ApiOperation("模板-数据源查询")
    public ResultBean dataSource(@PathVariable Integer type, Pageable pageable) {
        return workFlowProcessService.dataSource(type, pageable);
    }

    @PostMapping("location/config/save")
    @ApiOperation("位置服务编辑器-新增/修改")
    //@RequiresPermissions("workflow:location:config:save")
    public ResultBean locationConfigSave(@RequestBody WorkFlowLocationConfigBean<WorkFlowScreenConfigBean, WorkFlowRailAlarmConfigBean> bean) {
        return workFlowProcessService.locationConfigSave(bean);
    }

    @GetMapping("location/config/get")
    @ApiOperation(value = "位置服务编辑器-根据流程id查询", response = WorkFlowLocationConfigBean.class)
    public ResultBean processLocationConfig(Long processId) {
        try {
            return workFlowProcessService.processLocationConfig(processId);
        } catch (ApiCoreException er) {
            log.error(er.getMessage(), er);
            return ResultBean.fail(er.getCode(), er.getMessage());
        }
    }

    @PostMapping("print-template-save")
    @ApiOperation("流程-打印模板保存")
    @RequiresPermissions("workflow:print-template-save")
    public ResultBean printTemplateSave(@RequestBody @Valid WorkFlowPrintTemplateBean bean) {
        return workFlowProcessService.printTemplateSave(bean);
    }

    @GetMapping("print-template-get")
    @ApiOperation("流程-打印模板查询")
    public ResultBean printTemplateGet(@RequestParam("processId") Long processId) {
        return workFlowProcessService.printTemplateGet(processId);
    }

    @PostMapping("screen-type-save")
    @ApiOperation("大屏专栏类型保存")
    @RequiresPermissions("workflow:screen-type-save")
    public ResultBean screenTypeSave(@Valid @RequestBody WorkFlowScreenTypeBean bean) {
        return workFlowProcessService.screenTypeSave(bean);
    }

    @GetMapping("screen-type-page")
    @ApiOperation("大屏专栏类型查询")
    public ResultBean screenTypePage(Pageable pageable) {
        return workFlowProcessService.screenTypePage(pageable);
    }

    @GetMapping("screen-type-delete")
    @ApiOperation("大屏专栏类型删除")
    @RequiresPermissions("workflow:screen-type-delete")
    public ResultBean screenTypeDelete(Long id) {
        return workFlowProcessService.screenTypeDelete(id);
    }

    @GetMapping("all-process-map")
    @ApiOperation("获取所有流程实例")
    public ResultBean findAllProcessIdAndName() {
        return ResultBean.success(workFlowProcessService.findAllProcessIdAndName());
    }

    @PostMapping("saveCodeStrategy")
    @RequiresPermissions("workflow:add")
    @ApiOperation(value = "保存编码设置", response = WorkFlowProcessCodeStrategy.class)
    public ResultBean saveCodeStrategy(@RequestBody WorkFlowProcessCodeStrategyBean bean) {
        WorkFlowProcessCodeStrategy strategy = workFlowProcessService.saveCodeStrategy(bean);
        return ResultBean.success(strategy);
    }

    @GetMapping("findCodeStrategyById")
    @ApiOperation("查看编码设置")
    public ResultBean findCodeStrategyById(Long id) {
        WorkFlowProcessCodeStrategyBean strategyBean = workFlowProcessService.findCodeStrategyById(id);
        return ResultBean.success(strategyBean);
    }

    @GetMapping("pageCodeStrategy")
    @ApiOperation("分页查看编码规则")
    public ResultBean pageCodeStrategy(Pageable page, String name) {
        return workFlowProcessService.pageCodeStrategy(page, name);
    }

    @GetMapping("deleteCodeStrategyById")
    @RequiresPermissions("workflow:delete")
    @ApiOperation("删除编码规则")
    public ResultBean deleteCodeStrategyById(Long id) {
        return workFlowProcessService.deleteCodeStrategyById(id);
    }

    /**
     * 即时调用Schedule Job ,启动更新编码种子
     */
    @GetMapping("codeStrategyUpdateJob")
    @ApiOperation("更新编码种子Job")
    public ResultBean generateNotifyJob(Integer flag) {
        scheduleService.codeStrategyUpdateJob(flag);
        return ResultBean.defaultSuccessResult();
    }

    @PostMapping("/saveTemplate")
    @ApiOperation("保存打印模板-新版")
    public ResultBean addTemplate(@RequestBody WorkflowProcessPrintTemplate template) {
        boolean isSuccess = workflowProcessPrintTemplateService.saveOrUpdate(template);
        return ResultBean.success(isSuccess);
    }

    @PostMapping("/saveDefaultTemplate")
    @ApiOperation("设置默认打印模板-新版")
    public ResultBean addTemplate(Long oldDefaultTemplateId, Long newDefaultTemplateId) {
        workflowProcessPrintTemplateService.saveDefaultTemplate(oldDefaultTemplateId, newDefaultTemplateId);
        return ResultBean.defaultSuccessResult();
    }

    @PostMapping("/deleteTemplate")
    @ApiOperation("删除打印模板-新版")
    public ResultBean deleteTemplate(Long templateId) {
        WorkflowProcessPrintTemplate template = new WorkflowProcessPrintTemplate();
        template.setDeleteFlag("1");
        template.setId(templateId);
        return ResultBean.success(workflowProcessPrintTemplateService.updateById(template));
    }

    @GetMapping("/templateList")
    @ApiOperation("打印模板列表-新版")
    public ResultBean findTemplateList(Long processId) {
        return ResultBean.success(workflowProcessPrintTemplateService.findTemplateList(processId));
    }

    @GetMapping("/fillTemplateContent")
    @ApiOperation("打印模板数据填充-新版")
    public ResultBean fillTemplateContent(Long taskId, Long templateId) {
        try {
            return ResultBean.success(workflowProcessPrintTemplateService.fillTemplateContent(taskId, templateId));
        } catch (ApiCoreException er) {
            log.error(er.getMessage(), er);
            return ResultBean.fail(er.getCode(), er.getMessage());
        }
    }

    @GetMapping("getByBizTypeName")
    @ApiOperation("根据业务类型名称获取业务流程")
    public ResultBean getDynamicConfig(@RequestParam("bizTypeName")String bizTypeName) {
        List<SimpleSelectListBean> beanList = workFlowProcessService.getByBizTypeName(bizTypeName);
        return ResultBean.success(beanList);
    }
}
